/blog/
Moving the blog to to a text file based backend
So it occured to me that the amount of work it would take to make a traditional database powered CMS in Rust from scratch was more than I wanted to put into it. So I came up with an idea to rebuild it as a CMS based on plain textfiles, Markdown or HTML. Then as I started putting it into code it became obvious that this was a good idea. And I learned some new tricks in Rust so I thought I’d share.
For instance to get a directory listing in Rust is really easy:
let paths = fs::read_dir("/some/file/path/to/dir/").unwrap()
https://doc.rust-lang.org/std/fs/fn.read_dir.html
Which is simple, but comes with a catch. The directory contents are returned as path objects which display as OsStrings
instead of normal Strings
in an iterator. Which for a particular use case I needed, wasn’t working. But the solution was at hand in the standard library with to_string_lossy()
.
for item in paths {
let this_path = &item.unwrap().path();
...
title: String::from(this_path.file_stem().unwrap().to_string_lossy()),
Also I needed the file creation time which was available in fs::metadata()
but it also needed some massaging into something I could work with. So with the metadata object from .created()
:
actual_time = _time.duration_since(UNIX_EPOCH).unwrap().as_secs() as i64
Maybe not the safest way to do it, but the .as_secs()
returns a u64 value and I needed an i64 for Chrono NaiveDateTime::from_timestamp(actual_time, 0)
.
So basically I now have a struct filled with the 3 minimum pieces of data I need to make a blog workflow.
let new_content = MDContent {
created: read_file_creation_time(&this_path),
title: String::from(this_path.file_stem().unwrap().to_string_lossy()),
body: read_markdown_from_path(&this_path),
};
Throw the structs in a Vec and then get them minimally sorted via the "created" key of the struct with the Vec built in contents.sort_unstable_by_key(|x| x.created);
.
So this took less than a hundred lines of code and the original Diesel/Postgres code I wrote to do the same is about 200 lines. It doesn’t perceptually seem to be any faster or slower than the DB based code. It’s in a Git repository so I have versioning and easy backups. I can edit the posts in Obsidian. Seems like a bunch of wins, so maybe I’m onto something here?